package com.ruoyi.weiriya.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.WMember;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.Arith;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.weiriya.domain.*;
import com.ruoyi.common.core.domain.entity.WVehicle;
import com.ruoyi.weiriya.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.weiriya.mapper.WMemberChargeRecordMapper;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户充电记录Service业务层处理
 * 
 * @author lynn
 * @date 2023-08-01
 */
@Slf4j
@Service
public class WMemberChargeRecordServiceImpl extends ServiceImpl<WMemberChargeRecordMapper, WMemberChargeRecord> implements IWMemberChargeRecordService
{

    @Autowired
    private IWMemberService memberService;

    @Autowired
    private IWNonVipSettingService nonVipSettingService;

    @Autowired
    private IWVehicleService vehicleService;

    @Autowired
    private IWMessageService messageService;

    @Autowired
    private IWSocketTwoService socketTwoService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IWSettingService settingService;

    @Autowired
    private IWCompanyService companyService;

    @Autowired
    private IWMemberDepositRecordService depositRecordService;

    @Autowired
    private WMemberChargeRecordMapper memberChargeRecordMapper;

    private final String TOM_COOKIE_KEY = "TOM_COOKIE_KEY";

    @Transactional
    @Override
    public boolean saveWMemberChargeRecord(WMemberChargeRecord wMemberChargeRecord) {
        wMemberChargeRecord.setStartTime(new Date());
        WMember member = SecurityUtils.getLoginUser().getMember();

        WMemberDepositRecord depositRecord = depositRecordService.getOne(new LambdaQueryWrapper<WMemberDepositRecord>()
                .eq(WMemberDepositRecord::getMemberId, member.getId())
                .eq(WMemberDepositRecord::getState, 1));

        // 判断非ViP用户余额是否支持充电
        if(member.getMemberType() != 1) {
            if(StringUtils.isNull(depositRecord)){
                throw new ServiceException("未查询到入场信息！");
            }
            String areaId = depositRecord.getAreaId();
            wMemberChargeRecord.setAreaId(areaId);
            wMemberChargeRecord.setVipType(4);
            nonVipSettingService.checkLowestAmount(member, wMemberChargeRecord.getAreaId());
        }
        String transactionId;
        if(wMemberChargeRecord.getType() == 0) {
            // 查询当前用户是否存在未结束订单
            List<WMemberChargeRecord> chargeRecords = this.list(new LambdaQueryWrapper<WMemberChargeRecord>()
                    .eq(WMemberChargeRecord::getMemberId, SecurityUtils.getUserId())
                    .eq(WMemberChargeRecord::getState, 2)
                    .eq(WMemberChargeRecord::getType, 0));
            // 结束未停止计费的订单
            if(chargeRecords.size() > 0){
                throw new ServiceException("存在充电未结束的订单！");
            }
            // 插座通电 (1拖2)  获取从点业务号
            transactionId = socketTwoService.openOrCloseSocket(wMemberChargeRecord.getSocketId(), wMemberChargeRecord.getPortIndex(), 1);
        } else {
            // 查询当前用户是否存在未结束订单
            List<WMemberChargeRecord> chargeRecords = this.list(new LambdaQueryWrapper<WMemberChargeRecord>()
                    .eq(WMemberChargeRecord::getMemberId, SecurityUtils.getUserId())
                    .le(WMemberChargeRecord::getState, 2)
                    .eq(WMemberChargeRecord::getType, 1));
            if(chargeRecords.size() > 0){
                throw new ServiceException("存在充电未结束的订单！");
            }
            transactionId = openTom(wMemberChargeRecord);
        }
        if(StringUtils.isBlank(transactionId)){
            throw new ServiceException("插座开启失败！");
        }
        wMemberChargeRecord.setTransactionId(transactionId);

        // 获取车辆信息
        WVehicle vehicle = vehicleService.getOne(new LambdaQueryWrapper<WVehicle>()
                .eq(WVehicle::getMemberId, SecurityUtils.getUserId()));
        if(StringUtils.isNotNull(vehicle)) {
            wMemberChargeRecord.setVehicleType(vehicle.getVehicleChargeTypeId());
        }
        wMemberChargeRecord.setMemberId(member.getId());
        if(StringUtils.isNull(wMemberChargeRecord.getVipType())) {
            wMemberChargeRecord.setVipType(member.getVipType());
        }
        if(StringUtils.isNull(wMemberChargeRecord.getAreaId())) {
            wMemberChargeRecord.setAreaId(member.getAreaId());
        }

        wMemberChargeRecord.setState(1);

        // 检查小区是否设置此类型的价格
        if (wMemberChargeRecord.getVipType() == 4){
            WNonVipSetting nonVipSetting = nonVipSettingService.getWNonVipSettingByAreaId(wMemberChargeRecord.getAreaId());
            if (StringUtils.isNull(nonVipSetting)) {
                throw new ServiceException("价格异常，\n请联系管理员！");
            }
        }
        return this.save(wMemberChargeRecord);
    }

    @Transactional
    @Override
    public boolean updateWMemberChargeRecordById(WMemberChargeRecord wMemberChargeRecord) {

        // 获取记录信息
        WMemberChargeRecord chargeRecord = this.getById(wMemberChargeRecord.getId());


        if(wMemberChargeRecord.getType() == 0) {
            // 关闭插座
            socketTwoService.openOrCloseSocket(chargeRecord.getSocketId(), chargeRecord.getPortIndex(), 0);
        }

        Date date = new Date();
        if(wMemberChargeRecord.getStartTime() != null){
            date = wMemberChargeRecord.getStartTime();
        }
        long minute = 0;
        if(StringUtils.isNull(wMemberChargeRecord.getTotalDuration())){
            minute = (date.getTime() - chargeRecord.getStartTime().getTime()) / 60000;
            // 记录结束时间和总时长
            chargeRecord.setEndTime(date);
            chargeRecord.setTotalDuration(minute);
        } else {
            minute = wMemberChargeRecord.getTotalDuration();
            // 记录结束时间和总时长
            chargeRecord.setEndTime(wMemberChargeRecord.getEndTime());
            chargeRecord.setTotalDuration(minute);
        }
        // 计算价格
        WMember member = memberService.getById(chargeRecord.getMemberId());
        Integer vipType = member.getVipType();
        if(StringUtils.isNull(vipType) || vipType < 1 || vipType > 4){
            member.setVipType(4);
            vipType = 4;
            memberService.updateById(member);
        }
        chargeRecord.setVipType(vipType);
        log.info("memberrrrrrrrrrrrrrrrrrrrrrr{}",member);
        log.info("vipType-------------{}",vipType);
        // 不是VIP
        if(vipType == 4){
            // 获取当前小区的充电价格
            WNonVipSetting nonVipSetting = nonVipSettingService.getWNonVipSettingByAreaId(chargeRecord.getAreaId());

            if(StringUtils.isNull(nonVipSetting)){
                log.error("价格异常，请联系管理员！");
                throw new ServiceException("价格异常，\n请联系管理员！");
            }

            // 充电每小时金额
            Double chargeHourAmount = nonVipSetting.getChargeHourAmount();
            // 每天金额
            Double chargeDayAmount = nonVipSetting.getChargeDayAmount();

            // TODO　计算费用（目前逻辑：超过半小时算一个小时，未超过半小时不计费）
            // 换算为小时
            long round = Math.round((double) minute / 60D);
            Double amount = 0D;
            if(round <= 24){
                double amountTemp = Arith.mul(round, chargeHourAmount);
                if(Double.compare(amountTemp, chargeDayAmount) > 0){
                    amount = chargeDayAmount;
                } else {
                    amount = amountTemp;
                }

            } else {

                long l = round / 24;
                long l1 = round - (l * 24);
                double amountTemp = Arith.mul(l1, chargeHourAmount);
                double residue;
                if(Double.compare(amountTemp, chargeDayAmount) > 0){
                    residue = chargeDayAmount;
                } else {
                    residue = amountTemp;
                }
                amount = (chargeDayAmount * l) + residue;
            }
            // 记录本订单的金额
            chargeRecord.setAmount(amount);
            // 修改余额
            Double wallet = member.getWallet();
            double result = wallet - amount;
            member.setWallet(result > 0 ? result : 0D);

            // 获取押金警戒线
            WSetting wSetting = settingService.getById("CHARGING_DEPOSIT_WARNING_LINE");
            log.info("wSetting-----------------{}", wSetting);
            JSONObject jsonObject = JSONObject.parseObject(wSetting.getSettingValue());
            log.info("jsonObject-----------------{}", jsonObject);
            Double deposit = Double.valueOf(jsonObject.getString("amount"));
            log.info("deposit-----------------{}", deposit);
            if(result < deposit){
                messageService.remind(member, deposit);
            }
            memberService.updateById(member);
        } else {
            // VIP 免费
            chargeRecord.setAmount(0D);
        }
        chargeRecord.setState(3);
        chargeRecord.setRemarks(wMemberChargeRecord.getRemarks());

        // 发送消息
        WMessage wMessage = new WMessage();
        wMessage.setMessageType(1);
        wMessage.setMemberId(chargeRecord.getMemberId());
        wMessage.setUserType(2);
        wMessage.setMessageRange(1);
        wMessage.setAreaId(chargeRecord.getAreaId());
        wMessage.setMessageTitle("充电消费记录");
        wMessage.setMessageContent("开始时间：" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, chargeRecord.getStartTime()) + "</br>" +
                "结束时间：" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, chargeRecord.getEndTime()) + "</br>" +
                "消费：" + chargeRecord.getAmount());
        wMessage.setCreateTime(new Date());
        wMessage.setCreateBy("1");
        wMessage.setUpdateTime(new Date());
        wMessage.setUpdateBy("1");
        messageService.save(wMessage);


        return this.updateById(chargeRecord);
    }

    @Override
    public List<WMemberChargeRecord> getList(WMemberChargeRecord wMemberChargeRecord) {
        QueryWrapper<WMemberChargeRecord> queryWrapper = wMemberChargeRecord.queryWrapper();
        if(SecurityUtils.getLoginUser().isAdministrators()){
            if(StringUtils.isNotBlank(SecurityUtils.getLoginUser().getUser().getCompanyId())) {
                List<String> areaIdListByUserId = companyService.getAreaIdList();
                if(areaIdListByUserId.size() > 0) {
                    queryWrapper.in("mcr.area_id", areaIdListByUserId);
                } else {
                    return new ArrayList<>();
                }
            }
        } else{
            queryWrapper.eq("mcr.member_id", SecurityUtils.getUserId());
        }
        return memberChargeRecordMapper.getList(queryWrapper);
    }

    @Override
    public WMemberChargeRecord getWMemberChargeRecordById(String id) {
        return memberChargeRecordMapper.getWMemberChargeRecordById(id);
    }

    /**
     * 一拖十 查看插座状态
     */
    @Override
    public Object detailCharger(WMemberChargeRecord wMemberChargeRecord) {
        String url = "https://sp.tom-da.com/Manage/detail/charger/third/states";
        String param = "chargerSerialNum=" + wMemberChargeRecord.getSocketId();
        String body = HttpUtils.sendGet(url, param, Constants.UTF8, getTomCookie());
        JSONObject jsonObject = JSONObject.parseObject(body);
        Boolean success = jsonObject.getBoolean("success");
        if (success){
            return jsonObject.get("plug");
        }
        throw new ServiceException("此充电桩或充电口不存在!");
    }

    @Override
    public Object socketTwoDetailCharger(WMemberChargeRecord wMemberChargeRecord) {
        return socketTwoService.getStatusBySuid(wMemberChargeRecord.getSocketId());
    }

    @Override
    public void chargeCheckTask() {

        // 充电回调失败查询
        String url = "https://sp.tom-da.com/Manage/tp/op/callback/data/list";
        Date end = new Date();
        Date begin = DateUtils.addMinutes(end, -15);
        String param = "postFalseStartTime=" + begin +
                "&postFalseEndTime=" + end;
        String body = HttpUtils.sendGet(url, param, Constants.UTF8, getTomCookie());
        JSONObject jsonObject = JSONObject.parseObject(body);
        Integer total = jsonObject.getInteger("total");
        JSONArray jsonArray = jsonObject.getJSONArray("rows");
        for (int i = 0; i < total; i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            String stateType = object.getString("stateType");
            JSONObject order = object.getJSONObject("order");
            Long orderId = order.getLong("orderId");
            WMemberChargeRecord record = getByOrderId(orderId);
            // 获取订单详情
            JSONObject orderDetails = getOrderDetails(orderId);
            if(stateType.equals("Charging")){
                if(record.getState() == 1) {
                    record.setState(2);
                }
                String startTime = orderDetails.getString("startTime");
                record.setStartTime(DateUtils.parseDate(startTime));
                this.updateById(record);
            } else {
                String startTime = orderDetails.getString("startTime");
                String stopTime = orderDetails.getString("stopTime");
                if(record.getState() <= 2) {
                    record.setState(3);
                    record.setStartTime(DateUtils.parseDate(startTime));
                    record.setEndTime(DateUtils.parseDate(stopTime));
                    this.updateWMemberChargeRecordById(record);
                } else {
                    record.setStartTime(DateUtils.parseDate(startTime));
                    record.setEndTime(DateUtils.parseDate(stopTime));
                    this.updateById(record);
                }
            }
        }
    }

    /**
     * 一拖十插座 回调
     */
    @Override
    public Map tomCommon(JSONObject object) {
        log.info("汤姆达-回调事件：{}", object);

        String eventType = object.getString("eventType");
        String id = object.getString("id");

        JSONObject order = object.getJSONObject("order");

        Map<String, Object> map = new HashMap<>();
        map.put("id", id);

        if(eventType.equals("startAccepted")){ // 充电桩响应开始充电成功
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(2);
            record.setStartTime(new Date());
            this.updateById(record);
        } else if (eventType.equals("startRejected")){ // 充电桩响应开始充电失败
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(4);
        } else if (eventType.equals("stopAccepted")){ // 充电桩响应停止充电成功
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(3);
            Long seconds = order.getLong("chargeSeconds");
            record.setTotalDuration(seconds / 60);
            // 更新充电记录
            this.updateWMemberChargeRecordById(record);
        } else if (eventType.equals("stopRejected")){ // 充电桩响应停止充电失败
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(4);
        } else if (eventType.equals("startCharging")){ // 充电桩开始充电
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(2);
            record.setStartTime(new Date());
            this.updateById(record);
        } else if (eventType.equals("stopCharging")){ // 充电桩停止充电
            WMemberChargeRecord record = getByOrderId(order.getLong("orderId"));
            record.setState(3);
            Long seconds = order.getLong("chargeSeconds");
            record.setTotalDuration(seconds / 60);
            // 更新充电记录
            this.updateWMemberChargeRecordById(record);
        } else if (eventType.equals("updateCharging")){ // 充电桩更新充电中数据
            log.info("汤姆达：充电桩更新充电中数据回调事件：{}", object);
        } else {
            log.info("汤姆达-未知回调事件：{}", object);
        }
        map.put("accept", true);
        return map;
    }

    @Override
    public void tomChargeCheckTask() {
        List<WMemberChargeRecord> list = this.list(new LambdaQueryWrapper<WMemberChargeRecord>()
                .eq(WMemberChargeRecord::getType, 1)
                .le(WMemberChargeRecord::getState, 1));
        if(list.size() < 1) return;

        //创建线程池
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < list.size(); i++) {
            int finalI = i;
            service.submit(() -> {
                for (WMemberChargeRecord record : list) {

                    JSONObject order = getOrderDetails(Long.valueOf(record.getTransactionId()));

                    if(StringUtils.isNull(order)) continue;

                    String orderStatus = order.getString("orderStatus");
                    if(orderStatus.equals("CLOSED")){ // CHARGE
                        String startTime = order.getString("startTime");
                        String stopTime = order.getString("stopTime");
                        record.setStartTime(DateUtils.parseDate(startTime));
                        record.setEndTime(DateUtils.parseDate(stopTime));
                        if(startTime.equals(stopTime)){
                            record.setEndTime(new Date());
                        }
                        record.setRemarks(order.getString("orderCloseTypeText"));
                        this.updateWMemberChargeRecordById(record);
                    }
                }
            });
        }
    }

    @Override
    public void chargeAmountCheckTask() {
        List<WMemberChargeRecord> list = this.list(new LambdaQueryWrapper<WMemberChargeRecord>()
                .eq(WMemberChargeRecord::getVipType, 4)
                .eq(WMemberChargeRecord::getState, 2));
        Date now = new Date();

        ArrayList<WMemberChargeRecord> records = new ArrayList<>();

        Map<String, WNonVipSetting> settingMap = new HashMap<>();

        for (WMemberChargeRecord chargeRecord : list) {
            // 获取当前小区的充电价格
            WNonVipSetting nonVipSetting = settingMap.get(chargeRecord.getAreaId());
            if(StringUtils.isNull(nonVipSetting)) {
                nonVipSetting = nonVipSettingService.getWNonVipSettingByAreaId(chargeRecord.getAreaId());
                settingMap.put(nonVipSetting.getAreaId(), nonVipSetting);
            }
            // 用户信息
            WMember member = memberService.getById(chargeRecord.getMemberId());
            // 计算时长和价格
            Long minute = (now.getTime() - chargeRecord.getStartTime().getTime()) / 60000;

            // 充电每小时金额
            Double chargeHourAmount = nonVipSetting.getChargeHourAmount();
            // 每天金额
            Double chargeDayAmount = nonVipSetting.getChargeDayAmount();

            // TODO　计算费用（目前逻辑：超过半小时算一个小时，未超过半小时不计费）
            // 换算为小时
            long round = Math.round((double) minute / 60D);
            Double amount = 0D;
            if(round <= 24){
                double amountTemp = Arith.mul(round, chargeHourAmount);
                if(Double.compare(amountTemp, chargeDayAmount) > 0){
                    amount = chargeDayAmount;
                } else {
                    amount = amountTemp;
                }
            } else {
                long l = round / 24;
                long l1 = round - (l * 24);
                double amountTemp = Arith.mul(l1, chargeHourAmount);
                double residue;
                if(Double.compare(amountTemp, chargeDayAmount) > 0){
                    residue = chargeDayAmount;
                } else {
                    residue = amountTemp;
                }
                amount = (chargeDayAmount * l) + residue;
            }
            if(amount >= member.getWallet()){
                chargeRecord.setAmount(amount);
                chargeRecord.setState(3);
                chargeRecord.setTotalDuration(minute);
                chargeRecord.setEndTime(now);
                records.add(chargeRecord);
                // 关闭电源
                if(chargeRecord.getType() == 0){
                    // TODO 一拖二
                } else {
                    // 一拖十
                    stopTomSocket(chargeRecord);
                }
            }
        }

    }

    @Override
    public void timeoutSettlementTask() {
        List<WMemberChargeRecord> list = this.list(new LambdaQueryWrapper<WMemberChargeRecord>()
                .eq(WMemberChargeRecord::getState, 1)
                .eq(WMemberChargeRecord::getVipType, 4)
                .le(WMemberChargeRecord::getStartTime, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(new Date(), -1))));
        List<WMemberChargeRecord> changeRecordList = new ArrayList<>();
        List<WMember> changeMemberList = new ArrayList<>();
        for (WMemberChargeRecord record : list) {
            // 获取当前小区的停车价格
            WNonVipSetting nonVipSetting = nonVipSettingService.getWNonVipSettingByAreaId(record.getAreaId());
            // 每天金额
            Double stopDayAmount = nonVipSetting.getStopDayAmount();
            Date startTime = record.getStartTime();

            Long differenceDay = DateUtils.getDifferenceDay(startTime, new Date());

            Double withheldAmount = record.getWithheldAmount();
            Double nowAmount = stopDayAmount * differenceDay;

            if(withheldAmount >= nowAmount){
                continue;
            }
            // 新计算的金额大于已扣减的金额则再次扣减用户余额
            // 扣减用户余额
            WMember member = memberService.getById(record.getMemberId());
            Double wallet = member.getWallet();
            wallet = wallet - (nowAmount - withheldAmount);
            member.setWallet(wallet);
            // 从新记录已扣减金额
            record.setWithheldAmount(nowAmount);
            changeRecordList.add(record);
            changeMemberList.add(member);
        }
        this.updateBatchById(changeRecordList);
        memberService.updateBatchById(changeMemberList);
    }

    /**
    * 开启一拖十插座
    */
    public String openTom(WMemberChargeRecord wMemberChargeRecord) {

        // 检查用户
        WMember member = memberService.getById(SecurityUtils.getUserId());
        String bindTom = member.getBindTomId();
        if(StringUtils.isBlank(bindTom) || "1".equals(bindTom)){
            // 绑定用户
            bindTom(member);
        }
        // 开始充电
        String orderId = openTomSocket(wMemberChargeRecord);
        if(StringUtils.isBlank(orderId)){
            throw new ServiceException("开启插座失败，请联系管理员！");
        }
        return orderId;
    }

    /**
     * 一拖十 订单详情
     */
    private JSONObject getOrderDetails(Long orderId) {
        String url = "https://sp.tom-da.com/Manage/op/analyze/order/list/summary";
        String param = "stationId=-1" +
                "&summarySearchText=" + orderId
                + "&offset=0"
                + "&limit=1"
                + "&order=asc"
                + "&orderStatusText=all"
                + "&chargerDeviceTypeText=all"
                + "&searchTimeSelect=" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addMonths(new Date(), -1)) + " - " + DateUtils.getDate();
        log.info("param=============={}",param);
        try {
            String body = HttpUtil.sendPostReq(url, param, "utf-8", 1, null, getTomCookie());
            log.info("body--------{}", body);
            JSONObject jsonObject = JSONObject.parseObject(body);
            Integer total = jsonObject.getInteger("total");
            log.info("total--------{}", total);
            if(total <= 0){
                return null;
            } else {
                JSONArray rows = jsonObject.getJSONArray("rows");
                log.info("rows--------{}", rows);

                return rows.getJSONObject(0);
            }
        } catch (IOException e) {
            e.printStackTrace ( );
        }
        return null;
    }

    /**
     * 一拖十 获取指定时间段的所有订单
     */
    private JSONObject getOrderDetailsByTimes(String startTime, String EndTime) {
        String url = "https://sp.tom-da.com/Manage/op/analyze/order/list/summary";
        String param = "stationId=-1" +
                "&summarySearchText="
                + "&offset=0"
                + "&limit=1"
                + "&order=asc"
                + "&orderStatusText=all"
                + "&chargerDeviceTypeText=all"
                + "&searchTimeSelect=" + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addMonths(new Date(), -1)) + " - " + DateUtils.getDate();
        try {
            String body = HttpUtil.sendPostReq(url, param, "utf-8", 1, null, getTomCookie());
            JSONObject jsonObject = JSONObject.parseObject(body);
            Integer total = jsonObject.getInteger("total");
            if(total <= 0){
                return null;
            } else {
                JSONArray rows = jsonObject.getJSONArray("rows");
                return rows.getJSONObject(0);
            }
        } catch (IOException e) {
            e.printStackTrace ( );
        }
        return null;
    }

    private WMemberChargeRecord getByOrderId(Long orderId) {
        return this.getOne(new LambdaQueryWrapper<WMemberChargeRecord>()
                .eq(WMemberChargeRecord::getTransactionId, orderId));
    }

    /**
     * 一拖十插座开始充电
     */
    private String openTomSocket(WMemberChargeRecord record) {
        String url = "https://sp.tom-da.com/Manage/api/app/third/ebike/charger/"
                + SecurityUtils.getUserId() + "/startCharge/" + record.getSocketId() + "/" + record.getPortIndex();
        String param = "chargeStrategy=4" +
                "&chargeStrategyParam=600";
        try {
            String body = HttpUtil.sendPostReq(url, param, "utf-8", 1, null, getTomCookie());
            JSONObject jsonObject = JSONObject.parseObject(body);
            String orderId = jsonObject.getString("orderId");
            if(StringUtils.isBlank(orderId)){
                String errorMsg = jsonObject.getString("errorMsg");
                throw new ServiceException(errorMsg);
            }

            return orderId;
        } catch (IOException e) {
            e.printStackTrace ( );
        }
        return null;
    }

    /**
     * 一拖十插座开始充电
     */
    private void stopTomSocket(WMemberChargeRecord record) {
        String url = "https://sp.tom-da.com/Manage/api/app/third/ebike/charger/"
                + SecurityUtils.getUserId() + "/startCharge/" + record.getSocketId() + "/" + record.getPortIndex();
        String param = "chargeStrategy=4" +
                "&chargeStrategyParam=600";
        try {
            String body = HttpUtil.sendPostReq(url, param, "utf-8", 1, null, getTomCookie());
            JSONObject jsonObject = JSONObject.parseObject(body);
            Boolean success = jsonObject.getBoolean("success");
            if(!success){
                log.info("关闭插座失败：{}", jsonObject);
            }

        } catch (IOException e) {
            e.printStackTrace ( );
        }
    }

    /**
     * 一拖十插座绑定用户
     */
    private void bindTom(WMember member) {
        String url = "https://sp.tom-da.com/Manage/api/app/user/thirdPark/register";
        String param = "thirdParkUserId=" + member.getId();
        try {
            String body = HttpUtil.sendPostReq(url, param, "utf-8", 1, null, getTomCookie());
            JSONObject jsonObject = JSONObject.parseObject(body);
            String userId = jsonObject.getString("userId");
            member.setBindTomId(userId);
            memberService.updateById(member);
        } catch (Exception e) {
            e.printStackTrace ( );
        }
    }

    /**
     * 一拖十 获取登录Cookie
     */
    private String getTomCookie() {
        Object object = redisCache.getCacheObject(this.TOM_COOKIE_KEY);
        if(StringUtils.isNull(object)){
            String url = "https://sp.tom-da.com/Manage/login/third/mid";
            WSetting wSetting = settingService.getOne(new LambdaQueryWrapper<WSetting>()
                    .eq(WSetting::getId, "TOM_ACCOUNT"));
            String settingValue = wSetting.getSettingValue();
            JSONObject jsonObject = JSONObject.parseObject(settingValue);
            String username = jsonObject.getString("username");
            String password = jsonObject.getString("password");
            String param = "username=" + username +
                    "&password=" + password;
            try {
//
                String cookie = HttpUtil.sendPostReqGetCookie(url, param, "utf-8", 1, null);
                redisCache.setCacheObject(this.TOM_COOKIE_KEY, cookie, 25, TimeUnit.MINUTES);
                return cookie;
            } catch (Exception e) {
                e.printStackTrace ( );
            }
        }
        return (String)object;
    }

}
